use anyhow::anyhow;
use std::ops::{Add, AddAssign, Deref, Mul};

pub struct XVector<T> {
    data: Vec<T>,
}

impl<T> Deref for XVector<T> {
    type Target = Vec<T>;
    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

pub fn dot_product<T>(a: XVector<T>, b: XVector<T>) -> anyhow::Result<T>
where
    T: Copy + Default + Add<Output = T> + AddAssign + Mul<Output = T>,
{
    // a.len() => a.data.len() (Use Deref trait)
    if a.len() != b.len() {
        return Err(anyhow!("Dot product error, a.len != b.len"));
    }

    let mut sum = T::default();
    for i in 0..a.len() {
        sum += a[i] * b[i]; // Use Deref trait
    }
    Ok(sum)
}

impl<T> XVector<T> {
    pub fn new(data: impl Into<Vec<T>>) -> Self {
        Self { data: data.into() }
    }

    // pub fn len(&self) -> usize {
    //     self.data.len()
    // }

    // pub fn iter(&self) -> std::slice::Iter<T> {
    //     self.data.iter()
    // }
}

// 实现Index操作符
// impl<T> std::ops::Index<usize> for XVector<T> {
//     type Output = T;
//     fn index(&self, index: usize) -> &Self::Output {
//         &self.data[index]
//     }
// }
